#include "InventoryEvent.h"
#include "Log.h"
#include "Components/ComponentChest.h"
#include "BedWars.h"
#include "SubsystemBedWars.h"
#include "Components/ComponentClothing.h"
#include "Blocks/ClothingBlock.h"
#include "Network/PackageManager.h"
#include "Network/Packages/MessagePackage.h"
#include "GameSingleton.h"
#include "Player/PlayerData.h"
#include "Components/ComponentPlayer.h"
#include "Components/ComponentHealth.h"


using namespace PocketSurvival;

namespace BedWars
{
    static void sendMessage(ClientPtr client, const std::string & message)
    {
        std::shared_ptr<MessagePackage> package = std::make_shared<MessagePackage>(message);
        package->client = client;
        package->sendType = PackageSendType::TARGET;
        GameSingleton::packageManager->addSendPackageToQueue(package);
    }


    bool InventoryEvent::openPointInventory(std::shared_ptr<PlayerData> playerData, const Point3 &point, IInventory *inventory)
    {
        if(m_bedWarsCore->subsystemBedWars->mainStatue != BedWarsStatue::GameRunning && m_bedWarsCore->isEditMode == false)
        {
            return false;
        }
        return true;
    }

    // 移动物品
    bool InventoryEvent::playerHandleMoveItem(std::shared_ptr<PlayerData> playerData, IInventory *sourceInventory, uint32_t sourceSlotIndex, IInventory *targetInventory, int32_t targetSlotIndex, uint32_t count)
    {
        // 空气不准移动
        if (sourceInventory->getSlotValue(sourceSlotIndex) == 0)
        {
            return false;
        }
        if(m_bedWarsCore->isEditMode == false)
        {
            if(dynamic_cast<ComponentClothing*>(targetInventory) != nullptr && dynamic_cast<ComponentChest *>(sourceInventory) == nullptr)
            {
                int32_t cellValue = Terrain::ExtractContents(sourceInventory->getSlotValue(sourceSlotIndex));
                uint32_t cellCount = sourceInventory->getSlotCount(sourceSlotIndex);
                if(cellCount > 0)
                {
                    switch (cellValue)
                    {
                    case 131:   // 南瓜
                        sourceInventory->removeSlotItems(sourceSlotIndex, 1);
                        playerData->componentPlayer->componentHealth->heal(0.2f);
                        return false;
                    case 78:    // 烤鸟肉
                        sourceInventory->removeSlotItems(sourceSlotIndex, 1);
                        playerData->componentPlayer->componentHealth->heal(0.5f);
                        return false;
                    case 177:   // 面包
                        sourceInventory->removeSlotItems(sourceSlotIndex, 1);
                        playerData->componentPlayer->componentHealth->heal(1.0f);
                        return false;
                    case 89:    // 烤肉
                        sourceInventory->removeSlotItems(sourceSlotIndex, 1);
                        playerData->componentPlayer->componentHealth->heal(0.5f);
                        playerData->componentPlayer->componentHealth->invincibleTime = 6.0f;
                        return false;
                    case 206:   // 帆布
                        sourceInventory->removeSlotItems(sourceSlotIndex, 1);
                        playerData->componentPlayer->componentHealth->invincibleTime = 1.0f;
                        m_bedWarsCore->subsystemBedWars->toTeamHomePosition(playerData->componentPlayer);
                        return false;
                    }
                }
            }


            // 非编辑模式，不能把物品移动到箱子里面
            if(dynamic_cast<ComponentChest*>(targetInventory) != nullptr)
            {
                return false;
            }
            ComponentClothing *componentClothing = dynamic_cast<ComponentClothing*>(sourceInventory);
            if(componentClothing != nullptr)
            {
                int32_t clothingValue = componentClothing->getSlotValue(sourceSlotIndex);
                int32_t clothingIndex = ClothingBlock::GetClothingIndex(Terrain::ExtractData(clothingValue));
                // 13是外套
                if(clothingIndex == 30 || clothingIndex == 13 || clothingIndex == 16 || clothingIndex == 26 || clothingIndex == 14)
                {
                    sendMessage(playerData->client, "你不能脱下这件衣服");
                    if(m_bedWarsCore->subsystemBedWars->mainStatue == BedWarsStatue::GameRunning)
                    {
                        playerData->componentPlayer->componentHealth->injure(0.1f, entt::null, true, "恶意脱衣服，被幽灵死神带走了");
                    }
                    return false;
                }
                // Log::info(fmt::format("clothing index : {}", clothingIndex));
            }
            ComponentChest *chest = dynamic_cast<ComponentChest*>(sourceInventory);
            if(chest != nullptr)
            {
                if(m_bedWarsCore->subsystemBedWars->mainStatue == BedWarsStatue::GameRunning)
                {
                    if(sourceSlotIndex < 16 && (sourceSlotIndex % 8) < 4)
                    {
                        m_bedWarsCore->subsystemBedWars->transaction(chest, sourceSlotIndex, targetInventory, targetSlotIndex);
                    }
                }
                return false;
            }
        }
        return true;
    }

    // 点击移动物品
    bool InventoryEvent::playerHandleDragDrop(std::shared_ptr<PlayerData> playerData, IInventory *sourceInventory, uint32_t sourceSlotIndex, DragMode dragMode, IInventory *targetInventory, uint32_t targetSlotIndex, bool processingOnly)
    {
        // 空气不准移动
        if (sourceInventory->getSlotValue(sourceSlotIndex) == 0)
        {
            return false;
        }
        if(m_bedWarsCore->isEditMode == false)
        {
            if(dynamic_cast<ComponentClothing*>(targetInventory) != nullptr && dynamic_cast<ComponentChest *>(sourceInventory) == nullptr)
            {
                int32_t cellValue = Terrain::ExtractContents(sourceInventory->getSlotValue(sourceSlotIndex));
                uint32_t cellCount = sourceInventory->getSlotCount(sourceSlotIndex);
                if(cellCount > 0)
                {
                    switch (cellValue)
                    {
                    case 131:   // 南瓜
                        sourceInventory->removeSlotItems(sourceSlotIndex, 1);
                        playerData->componentPlayer->componentHealth->heal(0.2f);
                        return false;
                    case 78:    // 烤鸟肉
                        sourceInventory->removeSlotItems(sourceSlotIndex, 1);
                        playerData->componentPlayer->componentHealth->heal(0.5f);
                        return false;
                    case 177:   // 面包
                        sourceInventory->removeSlotItems(sourceSlotIndex, 1);
                        playerData->componentPlayer->componentHealth->heal(1.0f);
                        return false;
                    case 89:    // 烤肉
                        sourceInventory->removeSlotItems(sourceSlotIndex, 1);
                        playerData->componentPlayer->componentHealth->heal(0.5f);
                        playerData->componentPlayer->componentHealth->invincibleTime = 6.0f;
                        return false;
                    case 206:   // 帆布
                        sourceInventory->removeSlotItems(sourceSlotIndex, 1);
                        playerData->componentPlayer->componentHealth->invincibleTime = 1.0f;
                        m_bedWarsCore->subsystemBedWars->toTeamHomePosition(playerData->componentPlayer);
                        return false;
                    }
                }
            }

            // 非编辑模式，不能把物品移动到箱子里面
            if(dynamic_cast<ComponentChest*>(targetInventory) != nullptr)
            {
                return false;
            }
            ComponentClothing *componentClothing = dynamic_cast<ComponentClothing*>(sourceInventory);
            if(componentClothing != nullptr)
            {
                int32_t clothingValue = componentClothing->getSlotValue(sourceSlotIndex);
                int32_t clothingIndex = ClothingBlock::GetClothingIndex(Terrain::ExtractData(clothingValue));
                if(clothingIndex == 30 || clothingIndex == 13 || clothingIndex == 16 || clothingIndex == 26 || clothingIndex == 14)
                {
                    sendMessage(playerData->client, "你不能脱下这件衣服");
                    if(m_bedWarsCore->subsystemBedWars->mainStatue == BedWarsStatue::GameRunning)
                    {
                        playerData->componentPlayer->componentHealth->injure(0.1f, entt::null, true, "恶意脱衣服，被幽灵死神带走了");
                    }
                    return false;
                }
                // Log::info(fmt::format("clothing index : {}", clothingIndex));
            }
            ComponentChest *chest = dynamic_cast<ComponentChest*>(sourceInventory);
            if(chest != nullptr)
            {
                if(m_bedWarsCore->subsystemBedWars->mainStatue == BedWarsStatue::GameRunning)
                {
                    if(sourceSlotIndex < 16 && (sourceSlotIndex % 8) < 4)
                    {
                        m_bedWarsCore->subsystemBedWars->transaction(chest, sourceSlotIndex, targetInventory, targetSlotIndex);
                    }
                }
                return false;
            }
        }
        return true;
    }

    bool InventoryEvent::playerDrapDrop(ComponentPlayer *componentPlayer, const Vector3 &dropVelocity, IInventory *inventory, uint32_t slotIndex, uint32_t count)
    {
        if(m_bedWarsCore->isEditMode == false)
        {
            if(dynamic_cast<ComponentChest*>(inventory) != nullptr)
            {
                return false;
            }
            ComponentClothing *componentClothing = dynamic_cast<ComponentClothing*>(inventory);
            if(componentClothing != nullptr)
            {
                int32_t clothingValue = componentClothing->getSlotValue(slotIndex);
                int32_t clothingIndex = ClothingBlock::GetClothingIndex(Terrain::ExtractData(clothingValue));
                if(clothingIndex == 30 || clothingIndex == 13 || clothingIndex == 16 || clothingIndex == 26 || clothingIndex == 14)
                {
                    sendMessage(componentPlayer->playerData->client, "你不能脱下这件衣服");
                    if(m_bedWarsCore->subsystemBedWars->mainStatue == BedWarsStatue::GameRunning)
                    {
                        componentPlayer->componentHealth->injure(0.1f, entt::null, true, "恶意脱衣服，被幽灵死神带走了");
                    }
                    return false;
                }
            }

        }
        return true;
    }
} // namespace BedWars
